Conversation
|
🤖 CI Triage Agent — TL;DR: The "roce on worker 0" job failed because Full analysisSummary: Root cause: SIGILL inside the process while UCM installs mmap hooks by live-patching library code. Evidence this is unrelated to the PR: the branch Side observation (not the failure, but a latent bug worth filing): earlier in the same log, Implicated commit: unknown for the crash itself (pre-existing race); the most recent related change is c77bb48, shasson5 — "UCM/BISTRO: Increase grace time to reduce patch race (#11112)". PR commit a870f66 is not implicated. File: src/ucm/bistro/bistro.c:86-97 (time-based grace window + non-atomic Suggested fix:
Related: PR #11112 ("UCM/BISTRO: Increase grace time to reduce patch race", commit c77bb48) — prior mitigation of this same race; no open issue found matching "test_hooks Illegal instruction". |
|
@shasson5 please review. |
|
🤖 CI Triage Agent — TL;DR: The build failed only on the flaky timing-sensitive Full analysisSummary: Root cause: Evidence from the log: Implicated commit: Not the PR commit. The rwlock primitive/test originates from 8bbe776 "UCS: Introduce lightweight rwlock" (Artemy Kovalyov) — the only commit touching File: Suggested fix: Treat this as an unrelated flake for PR #11805 — retrigger the Azure "Tests new on worker 0" job, and rebase the branch after PR #11809 (which increases the rwlock test's sleep to remove the CI race) is merged. Longer term, make Related: #11809 (GTEST/UCS: Increase rwlock test sleep to avoid CI races); failing build PR #11805 |
|
🤖 CI Triage Agent — TL;DR: Full analysisSummary: UCP AM test over Root cause:
Implicated commit: [REDACTED:Hex High Entropy String] (PR #11805, branch File: test/gtest/ucp/test_ucp_am.cc:893-895 (crash site); per-EP traffic-class/AH-attribute code added by PR #11805 in Suggested fix:
Related: #11805, #11618, commit e7b7c86 "UCT/IB: Use global traffic class for RoCEv2 with auto configuration (#11105)"
|
|
🤖 Starting review — findings will be posted here when done. |
| * the transport's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
The new field and mask bit have no consumer in this PR — no transport reads ep_traffic_class. The doc states this is "currently implemented by the RC transport over mlx5 devices with DEVX enabled...", but the diff and PR head contain no implementation. If the API is split from the implementation on purpose, please reword the doc so it doesn't claim it is "currently implemented" until the RC mlx5 support lands, otherwise users will set it and silently get the iface default.
| * the interface's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
The new field and mask bit have no consumer in this PR — no transport reads ep_traffic_class. The doc states this is "currently implemented by the RC transport over mlx5 devices with DEVX enabled...", but the diff and PR head contain no implementation. If the API is split from the implementation on purpose, please reword the doc so it doesn't claim it is "currently implemented" until the RC mlx5 support lands.
|
Coverage gap: No test exercises the new API contract (e.g., a UCP ep-create path that sets |
0aa266e to
db57dab
Compare
|
🤖 Starting review — findings will be posted here when done. |
|
Residual coverage note (already raised in the prior review, not blocking): there is no test exercising the new field-mask paths and no implementation reads the new bits. If this is intentionally API-only ahead of the implementation, the "Currently implemented by the RC transport..." wording in both ucp_def.h and uct_v2.h is misleading and should be deferred until the implementation lands. |
|
@ybenvidia please avoid force-pushing during code review process |
|
🤖 Starting review — findings will be posted here when done. |
| * the transport's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
Misleading "Currently implemented by the RC transport over mlx5 devices with DEVX enabled..." wording. No code reads traffic_class from the params struct, so the documentation claims a working implementation that does not exist in this PR. This wording should be deferred until the implementation lands, or the PR description should state the API-only intent.
| * the interface's default traffic class for this endpoint only, using the | ||
| * same format. | ||
| * | ||
| * Currently implemented by the RC transport over mlx5 devices with DEVX |
There was a problem hiding this comment.
Misleading "Currently implemented by the RC transport over mlx5 devices with DEVX enabled..." wording. No code reads traffic_class from the params struct, so the documentation claims a working implementation that does not exist in this PR. This wording should be deferred until the implementation lands, or the PR description should state the API-only intent.
|
No test exercises the new API contract — no UCP ep-create or UCT connect_to_ep path sets the new field-mask bits ( |
|
🤖 CI Triage Agent — TL;DR: This is not a code/test failure — the "commit title" codestyle gate rejected the PR because one of its commits is titled Full analysisSummary: The Azure Pipelines "Codestyle / commit title" job (build 133025) exited with code 1 during its Bash step after validating the PR's commit titles. Root cause: The commit-title linter iterates over the commits in PR #11805 and requires each title to match UCX's convention
The Bash task then failed ( Implicated commit: File: No source file is at fault. The failing step is the "commit title" Bash task of the Codestyle stage in the Azure pipeline definition under Suggested fix: Rewrite the branch history to remove the non-conforming title: Simplest option, since Related: none (searches for prior "Bad commit title" reports returned only unrelated PRs: #11838, #11796, #11480, #11218, #2724)
|
|
LGTM |
| * This setting is optional. To enable it, the corresponding @ref | ||
| * UCP_EP_PARAM_FIELD_TRAFFIC_CLASS bit in the field mask must be set. | ||
| */ | ||
| uint8_t traffic_class; |
There was a problem hiding this comment.
This API change is tricky. We are trying to expose transport specific (TL) concept into UCP and we end up calling out explicitly RC/IB/ROCE. Would it make sense to define HIGH/LOW/etc. level and underneath implement relevant mapping ?
There was a problem hiding this comment.
@shamisp You're right, and I checked with Feroz Zahid on the QoS side — he says the same thing: DSCP is not what an application should be setting. So I'll rework the UCP side.
Proposed direction:
-
UCP: an abstract priority level instead of a traffic class — a small integer with 0 = highest priority. Feroz suggests reserving ~5 bits so additional levels can be given meaning later without changing the API (in practice only "high vs the rest" is used today, but this keeps the door open).
-
UCT: keep traffic_class as it is in this PR, since you said this layer is the right place for it.
-
The level-to-value mapping must be site-configurable, not hardcoded.
One design question before I code it: should UCP resolve the level into a traffic class — with the transport publishing its mapping through the iface attributes — or should the level be passed down to UCT and resolved there? The first keeps the UCT API exactly as you approved it; the second puts the mapping where the fabric config already lives.
Also @shasson5 what do you think ?
There was a problem hiding this comment.
You have two options in general:
- UCT exposing API that let's you query support levels and UCP doing the mapping
- Push this all the way down to UCT and UCT would do the level to value translation.
If we anticipate protocols orchestrating various priorities, I think (1) is correct path. If protocols are not expected to operate on QoS level, then (2) better choice.
There was a problem hiding this comment.
in our case protocols are not expected to deal with QoS (no special lanes/transport/protocols selection), so option 2 is the correct approach.
also I think maybe worth moving the new UCT level field to UCT EP creation API (uct_ep_params_t).
@shamisp WDYT?
There was a problem hiding this comment.
I think also option 2 it's the correct approach
There was a problem hiding this comment.
Move it to Ep creation instead of EP connect ? probably. Can single EP support multiple QoS levels ? This is a scalability question. Creating extra UCT EP and management those is not free.
There was a problem hiding this comment.
@ybenvidia do you have a requirement/design document that describes the specific use case/scenario that we need to support?
There was a problem hiding this comment.
as commented here, pls use more generic term for UCP
| * UCT_EP_CONNECT_TO_EP_PARAM_FIELD_TRAFFIC_CLASS bit in the field mask | ||
| * must be set. | ||
| */ | ||
| uint8_t traffic_class; |
There was a problem hiding this comment.
On UCT this makes much more sense but for UCP as I mentioned earlier it is not a good abstraction.
|
🤖 Starting review — findings will be posted here when done. |
| */ | ||
| ucs_sock_addr_t local_sockaddr; | ||
|
|
||
| /** |
There was a problem hiding this comment.
pls document the behavior when UCP_EP_PARAM_FIELD_QOS_LEVEL is not set, like err_mode/flags above; since 0 is the highest priority it's unclear whether an unset field means level 0 or that the transport keeps its configured default (UCX_IB_SL/UCX_IB_TRAFFIC_CLASS).
| * this abstract level to the prioritization mechanism provided by the | ||
| * underlying fabric. | ||
| * | ||
| * The number of levels a transport can distinguish is limited. Levels |
There was a problem hiding this comment.
can we report the number of distinguishable levels in uct_iface_attr? otherwise the user has no way to know which levels actually differ on a given transport.
|
🤖 Starting review — findings will be posted here when done. |
|
🤖 CI Triage Agent — TL;DR: Not a product failure — the Full analysisSummary: Azure Pipelines job "UCX PR (Codestyle / commit title)" build 137646 exited with code 1 after Root cause: The commit-title checker iterates over all non-merge commits in
The intermediate WIP/fixup commit Secondary CI-script bug: Implicated commit: The offending commit is the one titled File: Suggested fix:
Related: PR #11805 (#11805); checker introduced/narrowed by #11527 (#11527); style rules at https://github.com/openucx/ucx/wiki/Guidance-for-contributors#general-guidelines
|
| * This setting is optional. To enable it, the corresponding @ref | ||
| * UCP_EP_PARAM_FIELD_QOS_LEVEL bit in the field mask must be set. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
pls document what happens when UCP_EP_PARAM_FIELD_QOS_LEVEL is not set: since 0 is defined as the highest priority, "optional" alone does not tell whether an unset field means level 0 or "keep the transport/config default". Neighboring fields (err_mode, flags) state their default explicitly.
Impact: with the UCT_EP_PARAM_VALUE(..., 0) pattern used for path_index, an unset mask bit naturally lands on 0 == highest priority, so the ambiguity will likely become a behavior difference once the implementation lands.
| * which exceed that number are mapped to the lowest priority available, | ||
| * and transports which do not support prioritization ignore this value. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
can we state how this relates to the existing iface-level QoS configuration (UCX_IB_SL, UCX_IB_TRAFFIC_CLASS, both default auto)? an implementer needs to know whether the ep-level level overrides them, and what to do when UCT_EP_PARAM_FIELD_QOS_LEVEL is not set.
| * this abstract level to the prioritization mechanism provided by the | ||
| * underlying fabric. | ||
| * | ||
| * The number of levels a transport can distinguish is limited. Levels |
There was a problem hiding this comment.
the doc says the number of distinguishable levels is limited, but there is no way for the caller to learn it; why not also expose the supported level count (e.g. in uct_iface_attr_v2_t, and correspondingly at UCP level)? otherwise an app cannot map its levels portably and can only guess.
|
|
||
| /** | ||
| * Quality of service level of this endpoint, where 0 is the highest | ||
| * priority and larger values denote lower priority. The transport maps | ||
| * this abstract level to the prioritization mechanism provided by the | ||
| * underlying fabric. | ||
| * | ||
| * The number of levels a transport can distinguish is limited. Levels | ||
| * which exceed that number are mapped to the lowest priority available, | ||
| * and transports which do not support prioritization ignore this value. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
please move it back to uct_ep_connect
|
🤖 Starting review — findings will be posted here when done. |
|
🤖 CI Triage Agent — TL;DR: This isn't a code bug — the "commit title" codestyle job failed because PR #11805 contains a commit titled Full analysisSummary: Azure job Root cause: Implicated commit: The offending commit is the one titled File: Suggested fix: Rewrite the PR history to remove/rename the Related: Commit title rules: https://github.com/openucx/ucx/wiki/Guidance-for-contributors#general-guidelines; PR under test: #11805; check-range change: #11527
|
| * UCT_EP_CONNECT_TO_EP_PARAM_FIELD_QOS_LEVEL bit in the field mask must | ||
| * be set. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
why only in uct_ep_connect_to_ep_params_t and not in uct_ep_params_t? lanes created with uct_ep_create (connect-to-iface, e.g. dc_mlx5, ud, tcp, and the CM/sockaddr flow) have no way to receive ucp_ep_params_t::qos_level, so it would be silently dropped there.
| * This setting is optional. To enable it, the corresponding @ref | ||
| * UCP_EP_PARAM_FIELD_QOS_LEVEL bit in the field mask must be set. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
pls document the default when UCP_EP_PARAM_FIELD_QOS_LEVEL is not set - is it 0 (highest priority) or the transport's configured value (UCX_IB_SL / UCX_IB_TRAFFIC_CLASS)? the other optional fields in this struct state their default, and here the difference decides whether existing config is overridden.
|
Residual gaps (not posted, already covered by prior reviews): no test sets either new field-mask bit and no code reads them, so there is no hardware or gtest coverage of the new contract in this PR. |
|
LGTM. @brminich? |
|
@ybenvidia CI fails on commit title, please fix |
8222210 to
252671c
Compare
|
🤖 Starting review — findings will be posted here when done. |
| * This setting is optional. To enable it, the corresponding @ref | ||
| * UCP_EP_PARAM_FIELD_QOS_LEVEL bit in the field mask must be set. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
Only uct_ep_connect_to_ep_params_t got the matching field, so lanes connected via uct_ep_create (dc_mlx5, ud iface path, tcp) have no way to get this value. how do you plan to pass qos_level for those transports - add the field to uct_ep_params_t as well?
| * UCT_EP_CONNECT_TO_EP_PARAM_FIELD_QOS_LEVEL bit in the field mask must | ||
| * be set. | ||
| */ | ||
| uint8_t qos_level; |
There was a problem hiding this comment.
pls document which value is used when this bit is not set (transport config default, e.g. UCX_IB_SL/UCX_IB_TRAFFIC_CLASS?), like the other optional fields in this header do (dmabuf_fd, dmabuf_offset, sys_device). It matters here because 0 is a valid value meaning highest priority, so "not set" is not the same as 0.
|
Residual coverage gap (already raised in earlier reviews, not re-posted): no gtest or hardware path sets either new field-mask bit, and no code reads the new fields yet. |
|
🤖 Starting review — findings will be posted here when done. |
| * which exceed that number are mapped to the lowest priority available, | ||
| * and transports which do not support prioritization ignore this value. | ||
| * | ||
| * This setting is optional. To enable it, the corresponding @ref |
There was a problem hiding this comment.
pls document what happens when UCP_EP_PARAM_FIELD_QOS_LEVEL is not set (the other optional fields here do), and how it interacts with UCX_IB_TRAFFIC_CLASS/UCX_IB_SL; since 0 is the highest priority, an unset field should not be read as 0.
| UCT_EP_CONNECT_TO_EP_PARAM_FIELD_EP_ADDR_LENGTH = UCS_BIT(1) | ||
| UCT_EP_CONNECT_TO_EP_PARAM_FIELD_EP_ADDR_LENGTH = UCS_BIT(1), | ||
|
|
||
| /** QoS level */ |
There was a problem hiding this comment.
why only the connect_to_ep flow? transports connected via iface address (e.g. dc_mlx5) never see this param, so ucp_ep_params_t::qos_level cannot be honored on those lanes — can we add the same field to uct_ep_params_t?
| * this abstract level to the prioritization mechanism provided by the | ||
| * underlying fabric. | ||
| * | ||
| * The number of levels a transport can distinguish is limited. Levels |
There was a problem hiding this comment.
how does the user find out how many levels the transport distinguishes? maybe expose it in uct_iface_attr_v2_t, otherwise the mapping to the lowest priority is silent.
|
Residual coverage note: no test sets either new field-mask bit and no code reads the new fields, so the new contract is still untested in this PR. |
What
Add an optional per-endpoint traffic class to the UCP and UCT (v2) APIs:
ucp_ep_params_t::ep_traffic_class, enabled byUCP_EP_PARAM_FIELD_EP_TRAFFIC_CLASSuct_ep_connect_to_ep_params_t::ep_traffic_class, enabled byUCT_EP_CONNECT_TO_EP_PARAM_FIELD_EP_TRAFFIC_CLASSThis PR contains only the API definitions. The implementation follows in a
separate PR (see "Follow-up" below).
Why this cannot be done with the existing configuration
UCX already supports a traffic class, but only as an interface-wide
setting (
UCX_IB_TRAFFIC_CLASS), programmed into every QP created on thatinterface. It is a single value per process/interface.
The use case requires several different values simultaneously within the same
process and the same interface: endpoints belonging to different logical
groups must be tagged differently so the fabric can arbitrate between their
flows.
Concretely, for collective-communication QoS: a UCC team (≈ an MPI
communicator) is created with a priority, and every UCX endpoint opened for
that team must carry the corresponding traffic class, while endpoints of other
teams — on the same worker and the same device — keep a different one. A
higher-priority collective is then simply run on a higher-priority team.
This is a per-connection property, known only by the caller at connect
time. It cannot be derived from any existing parameter, and an environment
variable cannot express it, since one process needs multiple distinct values at
the same time. Hence the API addition.
The value is deliberately kept opaque and fabric-interpreted, matching what UCX
already does with the interface-wide setting: on RoCEv2 it ends up as the IP
DSCP code point, on IB as the GRH traffic class. No new semantics are
introduced — the same field UCX already programs simply becomes settable per
endpoint. Actual arbitration must still be configured on the fabric
(PFC/ETS/DSCP-to-priority mapping); UCX only carries the value.
Backward compatibility
Wire compatibility — unchanged. Nothing is added to the wire protocol. The
traffic class is not packed into UCX addresses and not exchanged in wireup
messages; it is applied locally, by each side, to its own QP context at connect
time. An old peer and a new peer interoperate with a bit-identical wire format.
Each side applies its own value to its own QP, with no negotiation. If only one
side sets it, that side's outgoing packets carry its traffic class and the peer
keeps the existing default — a partial QoS effect, but no protocol breakage.
This mirrors the existing behavior of the interface-wide setting.
ABI compatibility — preserved. Both new fields are appended at the end
of their respective structures, so no existing field offset changes.
Behavioral compatibility — none by default. The feature is strictly opt-in
through
field_mask. When the bit is not set, the code path is unchanged andfalls back to the existing interface-wide value, so current applications are
bit-for-bit unaffected.
Follow-up
Implementation PR: #11618 (UCP endpoint plumbing + RC mlx5 DEVX QP
programming), rebased on top of this one once merged.